package org.domeos.framework.api.service.global.impl;

import java.util.ArrayList;
import java.util.List;

import org.domeos.basemodel.HttpResponseTemp;
import org.domeos.basemodel.ResultStat;
import org.domeos.exception.K8sDriverException;
import org.domeos.framework.api.biz.cluster.ClusterBiz;
import org.domeos.framework.api.controller.exception.ApiException;
import org.domeos.framework.api.model.cluster.Cluster;
import org.domeos.framework.api.model.global.Resource;
import org.domeos.framework.api.model.global.ResourcePod;
import org.domeos.framework.api.model.global.ResourceShow;
import org.domeos.framework.api.service.global.ResourceService;
import org.domeos.framework.engine.k8s.util.Fabric8KubeUtils;
import org.domeos.framework.engine.k8s.util.KubeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import io.fabric8.kubernetes.api.model.Container;
import io.fabric8.kubernetes.api.model.Node;
import io.fabric8.kubernetes.api.model.NodeList;
import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.PodList;
import io.fabric8.kubernetes.api.model.Quantity;
import io.fabric8.kubernetes.api.model.ResourceRequirements;
import io.fabric8.kubernetes.client.Config;

import io.fabric8.kubernetes.client.ConfigBuilder;


import java.util.Map;


@Service
public class ResourceServiceImpl implements ResourceService {
	@Autowired
    ClusterBiz clusterBiz;
	
	
	public HttpResponseTemp<?> resourceCollect(String clusterName) {
		List<ResourceShow> rslsit = new ArrayList<ResourceShow>();
		Cluster cluster = clusterBiz.getClusterByName(clusterName);
		String master = cluster.getApi();
		Config config = new ConfigBuilder().withMasterUrl(master).build();
		try {
			
			KubeUtils client = Fabric8KubeUtils.buildKubeUtils(config);
			NodeList nodelist = client.listNode();
			List<ResourcePod> rplist = allPodInfo(clusterName);		
			for(Node node:nodelist.getItems()) {
				ResourceShow rs = new ResourceShow();
				String cpuall = node.getStatus().getCapacity().get("cpu").getAmount();
				String memoryall = node.getStatus().getCapacity().get("memory").getAmount();
				String podall = node.getStatus().getCapacity().get("pods").getAmount();
				rs.setNodename(node.getMetadata().getName());
				rs.setCpuall(Integer.parseInt(cpuall)*1000);
				rs.setCpuused(0);
				rs.setMemoryall(Integer.parseInt(memoryall.substring(0, memoryall.length()-2))/1024);
				rs.setMemoryused(0);
				rs.setPodall(Integer.parseInt(podall));
				rs.setPodused(0);
				for(ResourcePod rp:rplist) {
					if (rp.getNodename().equals(node.getMetadata().getName())) {
						rs.setCpuused(rs.getCpuused()+rp.getResource().getCpu());
						rs.setMemoryused(rs.getMemoryused()+rp.getResource().getMemory());
						rs.setPodused(rs.getPodused()+1);
					}
				}	
				rslsit.add(rs);
			}
			return ResultStat.OK.wrap(rslsit);
		}catch(K8sDriverException e) {
			return ResultStat.PARAM_ERROR.wrap("k8s connect error");
		}
		
//		List<ResourcePod> rplist = allPodInfo(clusterName);
//		for (ResourceShow rp:rplist) {
//			
//		}
	}
	public HttpResponseTemp<?> getPodInfo(String clusterName){
		return ResultStat.OK.wrap(allPodInfo(clusterName));
	}
	public List<ResourcePod> allPodInfo(String clusterName){
		List<ResourcePod> rplist = new ArrayList<ResourcePod>();
		Cluster cluster = clusterBiz.getClusterByName(clusterName);
        if (cluster == null) {
        	return rplist;
        }
		String master = cluster.getApi();
		Config config = new ConfigBuilder().withMasterUrl(master).build();
		try {
			KubeUtils client = Fabric8KubeUtils.buildKubeUtils(config);
			PodList podlist = client.listAllPod();
			for(Pod pod:podlist.getItems()) {
				ResourcePod rs = new ResourcePod();
				if(!pod.getStatus().getPhase().equals("Running")) {
					continue;
				}
				String podname = pod.getMetadata().getName();
				String nodename = pod.getSpec().getNodeName();
				String podip = pod.getStatus().getPodIP();
				List<Container> containers = pod.getSpec().getContainers();
				rs.setNodename(nodename);
				rs.setPodname(podname);
				rs.setResource(ResourceCount(containers));
				rs.setIp(podip);
				rplist.add(rs);
			}

		}catch (K8sDriverException e) {
			return rplist;
		}
		return rplist;
	}
	
	public Resource ResourceCount(List<Container> containers) {
		Resource resource = new Resource();
		int cpu = 0;
		int memory = 0;
		for(Container container:containers) {
			ResourceRequirements resources = container.getResources();
			if(resources == null) {
				continue;
			}
			Map<String, Quantity> requests = resources.getRequests();
			if (requests != null) {
				String cpustr = requests.get("cpu").getAmount();
				if (cpustr.endsWith("m")) {
					try {
						cpu += Integer.parseInt(cpustr.substring(0,cpustr.length()-1));
					}catch(NumberFormatException e){
						System.out.println("cpu 格式错误");
					}
				}else {
					cpu += Integer.parseInt(cpustr) * 1000;
				}

				String memorystr = requests.get("memory").getAmount();
				int rank = 1024;
				int size = 0;
				if (memorystr.endsWith("Ki") || memorystr.endsWith("Mi") || memorystr.endsWith("Gi") || memorystr.endsWith("Ti") || memorystr.endsWith("Pi") || memorystr.endsWith("Ei") ) {
					size = Integer.parseInt(memorystr.substring(0, memorystr.length()-2));
				}else if(memorystr.endsWith("K") || memorystr.endsWith("M") || memorystr.endsWith("G") || memorystr.endsWith("T") || memorystr.endsWith("P") || memorystr.endsWith("E")) {
					size = Integer.parseInt(memorystr.substring(0, memorystr.length()-1));
				}
				if (memorystr.endsWith("Ki") ) {
					memory += size / rank;
				}else if(memorystr.endsWith("K")){
					memory += size / rank;
				}else if (memorystr.endsWith("Mi") ) {
					memory += size;
				}else if(memorystr.endsWith("M")) {
					memory += size;
				}else if(memorystr.endsWith("Gi")) {
					memory += size * rank;
				}else if(memorystr.endsWith("G")) {
					memory += size * rank;
				}else if(memorystr.endsWith("Ti")) {
					memory += size * rank * rank;
				}else if(memorystr.endsWith("T")) {
					memory += size * rank * rank;
				}else if(memorystr.endsWith("Pi")) {
					memory += size * rank * rank * rank;
				}else if(memorystr.endsWith("P")) {
					memory += size * rank * rank * rank;
				}else if(memorystr.endsWith("Ei")) {
					memory += size * rank * rank * rank * rank;
				}else if(memorystr.endsWith("E")) {
					memory += size * rank * rank * rank * rank;
				}
			}
		}
		resource.setCpu(cpu);
		resource.setMemory(memory);
		return resource;
	}
	
	public int splitnum(String s,int len) {
		return Integer.parseInt(s.substring(0, s.length()-len-1));
	}
}
